home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 210_01 / percolxr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1985-11-13  |  16.0 KB  |  663 lines

  1. /* PERCOLXR.C    VERS:- 01.00  DATE:- 10/06/86  TIME:- 05:24:12 PM */
  2. /* 
  3. Description:
  4.  
  5. Simulation of percolation on a two-dimensional square lattice, 
  6. Option to block one or more regions of the lattice to prevent sites 
  7. being filled (approximately circular blocked region = 1,3,5,3,1).
  8. The algorithm is not efficient (300 seconds/1000 site 2-d sheet).
  9.  
  10. A percolative process is characterized by a percolation transition, a phase
  11. change at which long-range connectivity (e.g., a gel phase; conduction 
  12. across the sample; etc) suddenly appears.  Connectivity is defined by the
  13. extent of a cluster of filled sites adjacent (ie, connected) in the lattice.
  14. Long-range connectivity is equivalent to a cluster of infinite extent.
  15.  
  16. The percolation model applies to stochastic processes taking place 
  17. in a spatially disordered system.  
  18. Examples: 
  19.     gelation; 
  20.     flow in a porous medium; 
  21.     dilute magnets; 
  22.     conductivity of conductor-insulator composite materials.
  23.  
  24. For a discussion of percolation, see R. Zallen, "The Physics of Amorphous
  25. Solids", John Wiley, New York, 1983.
  26.  
  27. This program finds the fractional occupancy of the model lattice at the 
  28. percolation transition.  Lattice sites are filled randomly.  When each filled
  29. site is added to the lattice, connectivity is tested along one dimension
  30. of the lattice (ie, between one pair of arbitrarily chosen sides of the 
  31. lattice).  The point of the percolation transition is the point at which
  32. connectivity between sides first appears.
  33.  
  34. Because of the stochastic character of percolation, a simulation consists
  35. of the averaging of NRPT determinations of the percolation transition.
  36.  
  37. The program is set for looping over the simulation, with change in
  38. control parameters at each loop.
  39.  
  40. Requires sqrt() function.
  41.  
  42. J.A. Rupley, Tucson, Arizona
  43. Coded for the Eco-C Compiler, version 3.40
  44. */
  45.  
  46. #include <stdio.h>
  47. #include <ctrlcnst.h>
  48.  
  49. /*CHANGE TO FALSE IF SYSTEM NOT CONFIGURED FOR HAYES MODEM AS PUNCH-READER*/
  50. #define HAYES_MODEM FALSE
  51.  
  52. #define ARRAY_DIM 75
  53. #define NROW  10
  54. #define NCOL  10
  55. #define NRPT  20
  56. #define NBLOCKED 0
  57. #define NO_PRINT 20
  58.  
  59. #define PTS_BLOCKED 13        /*reset if change blocking pattern*/
  60.  
  61. #define FILLED '+'
  62. #define BLOCKED 'B'
  63. #define TRAIL 'O'
  64. #define BLANK ' '
  65.  
  66. int sum[ARRAY_DIM];
  67. char mast_array[ARRAY_DIM][ARRAY_DIM];
  68. char work_array[ARRAY_DIM][ARRAY_DIM];
  69.  
  70. int cnt_crit[100], cnt_blocked[100];
  71.  
  72. char del_i[] = {
  73.     -1,0,1,0,-1,0,1,0
  74. };
  75. char del_j[] = {
  76.     0,-1,0,1,0,-1,0,1
  77. };
  78. char test_block[] = {
  79.     0,0,1,0,0,
  80.     0,1,1,1,0,
  81.     1,1,1,1,1,
  82.     0,1,1,1,0,
  83.     0,0,1,0,0
  84. };
  85.  
  86. char str_buf[80];
  87. char title[160];
  88.  
  89. int xnrpt, xnrow, xncol;
  90. int nrpt, nrpt_1;
  91. int nsites¼ nsite_blocked;
  92. int no_print;
  93. int nblocked;
  94.  
  95. char i_last, j_last, k_last;
  96.  
  97. int block_sum, crit_sum;
  98.  
  99. double fcrt_avg, fcrt_var, fcrt_1var;
  100. double frct_avg, frct_var, frct_1var;
  101. double fblc_avg, fblc_var, fblc_1var;
  102. double frt1_avg, frt1_var, frt1_1var;
  103. double frt2_avg, frt2_var, frt2_1var;
  104. double fnrpt, fnrpt_1, funblocked, fsites; 
  105.  
  106. char i,j,k,ii,jj,kk,ll;
  107. int count;
  108. int pspecial;
  109. int s1, s2, s3;
  110. char clock_in[12];
  111.  
  112. void srand(), printf();
  113. int getchar(), strlen(), atoi(), irand(), bios();
  114. char *strcpy(), *strcat();
  115.  
  116. /* page eject*/
  117.  
  118.  
  119. main(argc,argv)
  120. int argc;
  121. char **argv;
  122. {
  123.                 /*PSPECIAL - LOOP OVER VARIED PARMS*/
  124.                 /*SETUP*/
  125. for (pspecial = 0; pspecial < 100; pspecial++) { 
  126.     switch (pspecial) {
  127.         case 0 :            /*case 0 used for setup*/
  128.             setup();
  129.             strcpy(title,
  130. "SIMULATION OF PERCOLATION ON A TWO-DIMENSIONAL SQUARE LATTICE"
  131.                 );
  132.             strcat(title,
  133. ""
  134.                 );        /*********insert title******/
  135.             printf("\n%s\n", title);
  136.             read_variables();    /*********optionally delete*/
  137.             continue;
  138.         case 1 :            /*case 1 to 99 = specials*/
  139.             break;
  140.         default:
  141.             exit();
  142.     }
  143.  
  144. nsites = xnrow * xncol;
  145. header_disp();
  146.  
  147.                 /*MAIN LOOP*/
  148.                 /*repeat determination of critical count 
  149.                     to obtain the average*/
  150. for (nrpt = 0; nrpt < xnrpt; nrpt++) {
  151.                 /*initialize mast_array 
  152.                     with optional blocking of sites*/
  153.     init_array();
  154.  
  155.                 /*SUB LOOP*/
  156.                 /*start of cycle of filling sites, 
  157.                     until have connection top-to-bottom*/
  158.                 /*the critical count is the number filled 
  159.                     at the point of first connection*/
  160.     while(TRUE) {
  161.                 /*find unfilled site, by random search*/
  162.         i = (irand() % xnrow) + 1;
  163.         j = (irand() % xncol) + 1;
  164.         if (mast_array[i][j] != BLANK)
  165.             continue;
  166.                 /*add new site to the master array*/
  167.         i_last = i;
  168.         j_last = j;
  169.         mast_array[i][j] = FILLED;
  170.         if (exit_test()) array_disp();
  171.                 /*if connection not possible, 
  172.                     go fill another site*/
  173.         if((cnt_crit[nrpt] = sum_filled(mast_array)) == 0)
  174.             continue;
  175.  
  176.                 /*test for connection*/
  177.                 /*if no connection, go fill another site*/
  178.         copy_array(mast_array, work_array);
  179.         if (!work_test())
  180.             continue;
  181.  
  182.                 /*EXIT SUBLOOP*/
  183.         break;
  184.     }
  185.  
  186.                 /*display mast_array and work_array, 
  187.                     side by side*/
  188.                 /*display blocked sites, if present*/
  189.                 /*display cnt_crit values and their 
  190.                     average and variance*/
  191.     if (nrpt < no_print) {
  192.         array_disp();
  193.         crit_calc();
  194.         crit_disp();
  195.     }
  196.     else
  197.         printf("working on cycle %d\n", (nrpt+1));
  198. }
  199.                 /*ALL DONE--TERMINATION OF MAIN LOOP*/
  200. prog_exit();
  201. }                /*END OF PSPECIAL LOOP*/
  202. }                /* END OF MAIN                */
  203. /* page eject*/
  204.  
  205.  
  206. int read_variables()
  207. {
  208.     printf
  209. ("\nDo you want to change values of program variables? (y/cr=>default): ");
  210.     str_buf[0] = getchar();
  211.     if ((str_buf[0] != 0x79) && (str_buf[0] != 0x59)) {
  212.         printf("\n");
  213.         return;
  214.     }
  215.     printf
  216. ("\nNew title? \n*:");
  217.     gets(str_buf);
  218.     if (strlen(str_buf)) {
  219.         strcpy(title, str_buf);
  220.         printf("     Another title line?\n*:");
  221.         gets(str_buf);
  222.         if (strlen(str_buf))
  223.             strcat(title,"\n");
  224.             strcat(title, str_buf);
  225.     }
  226.     printf("\n");
  227.     read_num(
  228. "How many array rows? (value/cr=>no change = %d): ", 
  229.         &xnrow);
  230.     printf("\n");
  231.     read_num(
  232. "How many array cols? (value/cr=>no change = %d): ", 
  233.         &xncol);
  234.     printf("\n");
  235.     read_num(
  236. "How many blocked regions? (value/cr=>no change = %d): ", 
  237.         &nblocked);
  238.     printf("\n");
  239.     read_num(
  240. "How many repeat determinations? (value/cr=>no change = %d): ", 
  241.         &xnrpt);
  242.     printf("\n");
  243.         read_num(
  244. "How many cycles do you want printed? (value/cr=>no change = %d): ", 
  245.         &no_print);
  246.  
  247.     printf("\n\n");
  248.     return;
  249. }                /*END OF READ_VARIABLES            */
  250.  
  251.  
  252.  
  253. int read_num(string, val)
  254. char *string;
  255. int *val;
  256. {
  257.     while (TRUE) {
  258.         printf(string, *val);
  259.         if (strlen(gets(str_buf)) == 0) return;
  260.         *val = atoi(str_buf);
  261.     }
  262.     return;
  263. }                /*END OF READ_NUM            */
  264.  
  265.  
  266.  
  267. int setup()
  268. {
  269.     char clock_in[12];
  270.     long temp;
  271.  
  272. /* set default values of xnrow, etc*/
  273.             xnrow = NROW;
  274.             xncol = NCOL;
  275.             xnrpt = NRPT;
  276.             nblocked = NBLOCKED;
  277.             no_print = NO_PRINT;
  278.             nsite_blocked = PTS_BLOCKED;
  279.  
  280. /*establish kernel for random number generator*/
  281.     read_clock();
  282.     temp = s1 + s2 + s3;
  283.     printf("\n\n temp = %ld = %d + %d + %d\n\n", temp, s1, s2, s3);
  284.     srand(temp);
  285.  
  286. /*fill array used to set block of points to be excluded from the fitting*/
  287.     for (i = 0; i < 25; i++)
  288.         if (test_block[i])
  289.             test_block[i] = BLOCKED;
  290.         else
  291.             test_block[i] = BLANK;
  292.  
  293.     return;
  294. }                /*END OF SETUP                */
  295.  
  296.  
  297.  
  298. #if HAYES_MODEM
  299. int read_clock()
  300. {
  301.                     /* Clock_in gives hhmmssx    */
  302.     hayes_chrono("RT\r", clock_in);
  303.     s1 = atoi(&clock_in[2]);
  304.     printf("\nTime, date and day =  %s ", clock_in);
  305.  
  306.                      /* Clock_in gives yymmdd    */
  307.     hayes_chrono("RD\r", clock_in);
  308.     s2 = atoi(&clock_in[2]);
  309.     printf("%s ", clock_in);
  310.  
  311.                     /* Clock_in gives  d = acsii #    */
  312.     hayes_chrono("RW\r", clock_in);
  313.     s3 = atoi(clock_in);
  314.     printf("%s \n", clock_in);
  315.  
  316.     return;
  317. }                /*END OF READ_CLOCK            */
  318.  
  319.  
  320.  
  321. int hayes_chrono(command, buffer)
  322. /* Send command to clock and return with string*/
  323. char *command, *buffer;
  324. {
  325.     strcpy(str_buf,"AT");
  326.     strcat(str_buf,command);        /* Form command            */
  327.  
  328.     for (i = 0; str_buf[i] != NULL; bios(PUNCH, str_buf[i++]));
  329.  
  330.     for (i = 0; i < 12; i++)
  331.         if ((str_buf[i] = bios(READER, 0)) == CR)
  332.             break;
  333.     str_buf[i] = '\0';
  334.  
  335.     strcpy(buffer, str_buf);
  336.     return;
  337. }                /* END OF HAYES_CHRONO            */
  338.  
  339.  
  340. #else
  341. int read_clock()
  342. {
  343.     printf("\n\nPlease hit three keys, not too quickly, to seed random number generator\n\n");
  344.     s1 = s2 = s3 = 0;
  345.     while (KBHIT)
  346.         getchar();
  347.     while (!KBHIT)
  348.         s1++;
  349.     while (KBHIT)
  350.         getchar();
  351.     while (!KBHIT)
  352.         s2++;
  353.     while (KBHIT)
  354.         getchar();
  355.     while (!KBHIT)
  356.         s3++;
  357.     while (KBHIT)
  358.         getchar();
  359. }                /*END OF READ_CLOCK IF NO MODEM IN SYSTEM */
  360. #endif
  361.  
  362.  
  363.  
  364. int init_array()
  365. {
  366.                 /*loop until success or 100 times*/
  367. ll = 100;
  368. while (ll--) {
  369.                 /*zero arrays*/
  370.     for (i = 0; i < ARRAY_DIM; i++) {
  371.         sum[i] = 0;
  372.         for (j = 0; j < ARRAY_DIM; j++)
  373.             mast_array[i][j] = work_array[i][j] = BLANK;
  374.     }
  375.  
  376.                 /*exclude block of sites*/
  377.                 /*count excluded sites*/
  378.     cnt_crit[nrpt] = cnt_blocked[nrpt] = 0;
  379.     if (!nblocked) return;
  380.     for (k = 0; k < nblocked; k++) {
  381.         while (TRUE) {
  382.             i = (irand() % xnrow) + 1;
  383.             j = (irand() % xncol) + 1;
  384.             if ((i > 2) && (i < xnrow - 1) 
  385.                     && (j > 2) && (j < xncol - 1)) {
  386.                 kk = 0;
  387.                 for (ii = (i - 2); ii < (i + 3); ii++)
  388.                 for (jj = (j - 2); jj < (j + 3); kk++, jj++)
  389.                     if ((mast_array[ii][jj] != BLOCKED)
  390.                           && (test_block[kk] == BLOCKED)){
  391.                     mast_array[ii][jj] = BLOCKED;
  392.                     cnt_blocked[nrpt]++;
  393.                     }
  394.                 break;
  395.             }
  396.         }
  397.     }
  398.                 /*test for impermeable barrier to connection*/
  399.     for (i = 1; i < (xnrow + 1); i++)
  400.         for (j = 1; j < (xncol + 1); j++)
  401.             if (mast_array[i][j] != BLOCKED)
  402.                 work_array[i][j] = FILLED;
  403.     iµ (work_test()⌐ 
  404.         return;
  405. }
  406. printf("\nFailure in array initialization\n");
  407. prog_exit();
  408. exit();
  409. }                /*END OF INIT_ARRAY            */
  410.  
  411.  
  412.  
  413. int exit_test()
  414. {
  415.     if (KBHIT) {
  416.         str_buf[0] = getchar();
  417. printf("\ntype x or X to exit or any other character to continue: ");
  418.         str_buf[0] = getchar();
  419.         if ((str_buf[0] == 0x58) || (str_buf[0] == 0x78)) {
  420.             prog_exit();
  421.             exit();
  422.         }
  423.         return TRUE;
  424.     }
  425.     return FALSE;
  426. }                /*END OF EXIT_TEST            */
  427.  
  428.  
  429.  
  430. int prog_exit()
  431. {
  432.     header_disp();
  433.     nrpt = nrpt - 1;
  434.     crit_calc();
  435.     crit_disp();
  436.     printf("\n\n\n\f");
  437.     return;
  438. }                /*END OF PROG_EXIT            */
  439.  
  440.  
  441.  
  442. int header_disp()
  443. {
  444.     printf("\n\n%s\n", title);
  445. #if HAYES_MODEM
  446.     read_clock();
  447. #endif
  448.     printf
  449. ("\nSimulation of percolation on a two-dimensional square lattice.");
  450.     printf
  451. ("\nThe array size is %d rows by %d columns, %d sites total.", 
  452.         xnrow, xncol, nsites);
  453.     printf
  454. ("\nThere are %d regions of %d sites blocked from filling.\n",
  455.         nblocked, nsite_blocked);
  456.     return;
  457. }                /*END OF HEADER_DISP            */
  458.  
  459.  
  460.  
  461. int array_disp()
  462. /*display master array and working array side-by-side, if possible*/
  463. /*display blocked sites, in mast_array*/
  464. /*display trail of the work_test pointer, in work_array*/
  465. /*display coordinates of last site filled*/
  466. {
  467.     printf("\n");
  468.     for (i = 1; i < (xnrow + 1); i++) {
  469.         printf("\n");
  470.         for (j = 1; j < (xncol + 1); j++)
  471.             printf("%c", mast_array[i][j]);
  472.         if (xncol < 38) {
  473.             printf("   ");
  474.             for (j = 1; j < (xncol + 1); j++)
  475.                 printf("%c", work_array[i][j]);
  476.         }
  477.     }
  478.     if (xncol > 37) {
  479.         printf("\n\n\n");
  480.         for (i = 1; i < (xnrow + 1); i++) {
  481.             printf("\n");
  482.             for (j = 1; j < (xncol + 1); j++)
  483.                 printf("%c", work_array[i][j]);
  484.         }
  485.     }
  486.     printf("\n\n nrpt=%d   cnt_crit[nrpt]=%d   ",
  487.         nrpt, cnt_crit[nrpt]);
  488.     printf("          i_last=%d   j_last=%d\n", i_last, j_last);
  489.     return;
  490. }                /* END OF ARRAY_DISP            */
  491.  
  492.  
  493.  
  494. int crit_disp()
  495. /*display critical counts and fractions--averages and variances*/
  496. {
  497. if (nblocked) {
  498.     printf("\nList of all counts of blocked sites\n");
  499.     for (i = 0; i < (nrpt + 1); i++)
  500.         printf("%4d%c", cnt_blocked[i], 
  501.             ((i % 10) == 9 || i == nrpt) ? '\n' : ' ');
  502. }
  503.  
  504.     printf
  505. ("\nList of all counts of filled sites at the critical point\n");
  506.     for (i = 0; i < (nrpt + 1); i++)
  507.         printf("%4d%c", cnt_crit[i], 
  508.             ((i % 10) == 9 || i == nrpt) ? '\n' : ' ');
  509.  
  510.     
  511.     printf(
  512. "\n\n   critical count =%10.2f     sample_var=%10.2f   avg_var=%10.2f",
  513.         fcrt_avg, fcrt_var, fcrt_1var);
  514.     printf(
  515.   "\n   critical/total =%10.5f     sample_var=%10.7f   avg_var=%10.7f", 
  516.         frct_avg, frct_var, frct_1var);
  517.  
  518. if (nblocked) {
  519.     printf(
  520. "\n\n   blocked sites  =%10.2f     sample_var=%10.2f   avg_var=%10.2f", 
  521.         fblc_avg, fblc_var, fblc_1var);
  522.     printf(
  523.   "\n   blocked/total  =%10.5f     sample_var=%10.7f   avg_var=%10.7f", 
  524.         frt1_avg, frt1_var, frt1_1var);
  525.     printf(
  526.   "\n   critical/unblkd=%10.5f     sample_var=%10.7f   avg_var=%10.7f", 
  527.         frt2_avg, frt2_var, frt2_1var);
  528. }
  529.     printf("\n\n\n");
  530.     return;
  531. }                      /* END OF CRIT_DISP            */
  532.  
  533.  
  534.  
  535. int crit_calc()
  536. /*calculate averages and variances of critical counts and fractions*/
  537. {
  538.     fnrpt = nrpt;
  539.     fnrpt_1 = nrpt + 1;
  540.     fsites = nsites;
  541.     crit_sum = 0;
  542.     for (i = 0; i < nrpt + 1; i++)
  543.         crit_sum = crit_sum + cnt_crit[i];
  544.  
  545.     fcrt_avg = (double) crit_sum / fnrpt_1;
  546.     fcrt_var = 0;
  547.     if (nrpt > 0) {
  548.         for (i = 0; i< (nrpt + 1); i++)
  549.             fcrt_var = fcrt_var + ((double) cnt_crit[i] - fcrt_avg) 
  550.                     * ((double) cnt_crit[i] - fcrt_avg);
  551.         fcrt_var = fcrt_var / fnrpt;
  552.     }
  553.     fcrt_1var = fcrt_var / fnrpt_1;
  554.     frct_avg = fcrt_avg / fsites;
  555.     frct_var = fcrt_var / (fsites * fsites);
  556.     frct_1var = fcrt_1var / (fsites * fsites);
  557.  
  558.                 /*calculations if blocked regions present*/
  559.     if (!nblocked) return;
  560.     block_sum = 0;
  561.     for (i = 0; (i < (nrpt + 1)) && (cnt_blocked[i] != 0); i++)
  562.         block_sum = cnt_blocked[i] + block_sum;
  563.  
  564.     fblc_avg = block_sum / fnrpt_1;
  565.     fblc_var = 0;
  566.     if (nrpt > 0) {
  567.         for (i = 0; i< (nrpt + 1); i++)
  568.             fblc_var = fblc_var + ((double) cnt_blocked[i] - fblc_avg) 
  569.                 * ((double) cnt_blocked[i] - fblc_avg);
  570.         fblc_var = fblc_var / fnrpt;
  571.     }
  572.     fblc_1var = fblc_var / fnrpt_1;
  573.     frt1_avg = fblc_avg / fsites;
  574.     frt1_var = fblc_var / (fsites * fsites);
  575.     frt1_1var = fblc_1var / (fsites * fsites);
  576.  
  577.     funblocked = fsites - fblc_avg;
  578.     frt2_avg = fcrt_avg / funblocked;
  579.     frt2_var = (frt2_avg * frt2_avg * fblc_var + fcrt_var)
  580.             / funblocked / funblocked;
  581.     frt2_1var = (frt2_avg * frt2_avg * fblc_1var + fcrt_1var)
  582.             / funblocked / funblocked;
  583.     return;
  584. }                /*END OF CRIT_CALC            */
  585.  
  586.  
  587. int sum_filled(array)
  588. char array[ARRAY_DIM][ARRAY_DIM];
  589. /*sum filled sites of array, by row*/
  590. /*return 0 if any row is zero (which means there can be no connection
  591.     between top and bottom edges (rows))*/
  592. /*else return count of all filled sites in array*/
  593. {
  594.     count = 0;
  595.     for (i = 1; i < (xnrow + 1); i++) {
  596.         sum[i] = 0;
  597.         for (j = 1; j < (xncol + 1); j++)
  598.             if (array[i][j] == FILLED)
  599.                 sum[i] = sum[i] + 1;
  600.         if (sum[i] == 0)
  601.             return 0;
  602.         count = count + sum[i];
  603.     }
  604.     return count;
  605. }                /* END OF SUM_FILLED            */
  606.  
  607.  
  608.  
  609. int copy_array(source, dest)
  610. char source[ARRAY_DIM][ARRAY_DIM], dest[ARRAY_DIM][ARRAY_DIM];
  611. /*copy only filled sites, blank others, ie the blocked sites*/
  612. {
  613.     for (i = 0; i < (xnrow + 2); i++)
  614.         for (j = 0; j < (xncol + 2); j++)
  615.             if (source[i][j] == FILLED)
  616.                 dest[i][j] = FILLED;
  617.             else
  618.                 dest[i][j] = BLANK;
  619.     return;
  620. }                /*END OF COPY_ARRAY            */
  621.  
  622.  
  623.  
  624. int work_test()
  625. /*move a pointer around the outside left edge of each sub-pattern*/
  626. /*starting at a filled site on the top row*/
  627. /*return true if reach bottom row, return false if no connection*/
  628. /*the arrays i_del and j_del hold a sequence of trial moves*/
  629. /*that maintains the pointer on the outside left edge of a pattern*/
  630. /*the pointer should either reach the bottom row or return to the top row*/
  631. /*if it returns to the top row, the search along the top edge continues*/
  632. /*mark trail of pointer with a string of TRAIL values*/
  633. {
  634.     for (j = 1; j < (xncol + 1); j++) {
  635.         if (work_array[1][j] == BLANK || work_array[2][j] == BLANK)
  636.             continue;
  637.         k = 2;
  638.         i = 2;
  639.         work_array[1][j] = TRAIL;
  640.         work_array[2][j] = TRAIL;
  641.         while (i > 1) {
  642.             if ((k_last = k % 4) == 0)
  643.                 k_last = 4;
  644.             for (k = (k_last - 1); k < (k_last + 3); k++) {
  645.                 ii = i + del_i[k];
  646.                 jj = j + del_j[k];
  647.                 if (work_array[ii][jj] != BLANK) {
  648.                     i = ii;
  649.                     j = jj;
  650.                     work_array[i][j] = TRAIL;
  651.                     break;
  652.                 }
  653.             }
  654.             if (i == xnrow)
  655.                 return TRUE;
  656.         }
  657.     }
  658.     return FALSE;
  659. }                /*END OF WORK_TEST            */
  660.  
  661.  
  662.  
  663.